package com.cy.ppj.service.account.impl;

import com.cy.ppj.comm.utils.JsonObjectMapper;
import com.cy.ppj.comm.utils.SpringContextUtils;
import com.cy.ppj.dao.mapper.user.BankMapper;
import com.cy.ppj.model.Result;
import com.cy.ppj.model.doc.BankCardBindLog;
import com.cy.ppj.model.doc.BankCardInfo;
import com.cy.ppj.model.domian.user.Bank;
import com.cy.ppj.model.domian.user.UserInfo;
import com.cy.ppj.service.BaseService;
import com.cy.ppj.service.account.BankCardService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @description: 绑定银行卡
 * @author: Ocean
 * @create: 2018-08-02 14:34
 **/
@Slf4j
@Service("AliBankCardServiceImpl")
public class AliBankCardServiceImpl extends BaseService implements BankCardService {

    @Autowired
    private RestTemplate restTemplate;
    private HttpEntity httpEntity;

    @Value("${bankcard.location-query-url}")
    private String queryUrl;
    @Value("${bankcard.verify-url}")
    private String verifyUrl;
    @Value("${bankcard.app-code}")
    private String appCode;

    @Autowired
    private BankCardCacheService bankCardCacheService;
    @Autowired
    private BankMapper bankMapper;

    @PostConstruct
    private void initHttpEntity() {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "APPCODE ".concat(appCode));
        httpEntity = new HttpEntity(null, headers);
    }

    @Override
    public Result verifyBankCard(UserInfo userInfo) {

        //查询是否有历史记录
        BankCardBindLog historyLog = bankCardCacheService.queryBankCardBindLog(userInfo.getBankCard());
        if (historyLog != null) {
            log.info("验证银行卡[{}],获取历史数据。", userInfo.getBankCard());
            return Result.success("", historyLog.getData());
        }

        Map<String, String> params = new HashMap<>();
        params.put("mobile", userInfo.getBankMobile());
        params.put("bankcard", userInfo.getBankCard());
        params.put("cardNo", userInfo.getIdNo());
        params.put("realName", userInfo.getRealName());
        log.info("银行卡[{}]四要素验证。params: {}", userInfo.getBankCard(), params);

        ResponseEntity<String> responseEntity = restTemplate.exchange(verifyUrl, HttpMethod.GET, httpEntity, String.class, params);
        if (!HttpStatus.OK.equals(responseEntity.getStatusCode())) {
            return Result.fail("验证银行卡失败");
        }
        log.info("银行卡四要素验证回调:{}", responseEntity.getBody());

        Map<String, Object> body = JsonObjectMapper.read(responseEntity.getBody(), Map.class);
        if (!Integer.valueOf(0).equals(body.get("error_code"))) {
            return Result.fail(body.get("reason")+"");
        }

        Map<String, Object> result = (Map) body.get("result");

        //更新回调日志
        BankCardBindLog bankCardBindLog = new BankCardBindLog();
        bankCardBindLog.setBankCard(userInfo.getBankCard());
        bankCardBindLog.setData(result);
        bankCardBindLog.setCreateTime(new Date());
        bankCardCacheService.insertBankCardBindLog(bankCardBindLog);
        log.info("记录银行卡信息");

        return Result.success("", result);
    }

    @Override
    @Transactional
    public void insertBank(Bank bank) {
        Bank dbBank = new Bank();
        dbBank.setBankNo(bank.getBankNo());
        int count = bankMapper.selectCount(dbBank);
        if (count <= 0) {
            bankMapper.insertSelective(bank);
        }
    }

    @Override
    public Result queryBankCard(String bankCard) {

        //查询历史数据
        BankCardInfo historyInfo = bankCardCacheService.queryBankCaedInfo(bankCard);
        if (historyInfo != null) {
            log.info("查询银行卡归属地[{}],获取历史数据。", bankCard);
            return Result.success("", historyInfo.getData());
        }

        //拼接参数
        Map<String, Object> params = new HashMap<>();
        params.put("apiversion", "2.0.5");
        params.put("bankcard", bankCard);
        log.info("银行卡[{}]查询归属地。param:{}", bankCard, params);

        //发起请求
        ResponseEntity<String> responseEntity = restTemplate.exchange(queryUrl, HttpMethod.GET, httpEntity, String.class, params);
        
        if (!HttpStatus.OK.equals(responseEntity.getStatusCode())) {
            return Result.fail("查询银行卡信息失败");
        }
        log.info("银行卡归属地查询回调:{}", responseEntity.getBody());

        Map<String, Object> body = JsonObjectMapper.read(responseEntity.getBody(), Map.class);
        if (!Integer.valueOf(0).equals(body.get("error_code"))) {
            return Result.fail(body.get("reason")+"");
        }

        Map<String, Object> result = (Map) body.get("result");

        //记录数据
        BankCardInfo bankCardInfo = new BankCardInfo();
        bankCardInfo.setBankCard(bankCard);
        bankCardInfo.setData(result);
        bankCardInfo.setCreateTime(new Date());
        bankCardCacheService.insertBankCaedInfo(bankCardInfo);
        log.info("记录银行卡信息");

        try {
            String bankNo = result.get("banknum").toString();
            String bankName = result.get("bankname").toString();
            Object iconImg = result.get("bankimage");
            Object code = result.get("abbreviation");
            Bank bank = new Bank();
            bank.setBankNo(bankNo);
            bank.setBankName(bankName);
            bank.setIconImg(iconImg == null ? null : String.valueOf(iconImg));
            bank.setCode(code == null ? null : String.valueOf(code));
            bank.setCreateTime(new Date());
            SpringContextUtils.getBean(BankCardService.class).insertBank(bank);
        } catch (Exception e) {
            log.error("保存银行信息：", e);
        }

        return Result.success("", result);
    }
}
